Inside Macintosh: Sound

| Previous | Chapter contents | Chapter top | Section top | Next |

Setting Up Double Buffers

Before you can call SndPlayDoubleBuffer , you need to allocate two buffers (of type SndDoubleBuffer ), fill them both with data, set the flags for the two buffers to dbBufferReady , and then fill out a record of type SndDoubleBufferHeader with the appropriate information. Listing 1-44 illustrates how you can accomplish these tasks.

Listing 44 Setting up double buffers

CONST
    kDoubleBufferSize = 4096;               {size of each buffer (in bytes)}
TYPE
    LocalVars =                             {variables used by the doubleback procedure}
    RECORD
        bytesTotal:         LongInt;        {total number of samples}
        bytesCopied:        LongInt;        {number of samples copied to buffers}
        dataPtr:            Ptr;            {pointer to sample to copy}
    END;
    LocalVarsPtr = ^LocalVars;

{This function uses SndPlayDoubleBuffer to play the sound specified.}
FUNCTION MyDBSndPlay (chan: SndChannelPtr; sndHeader: SoundHeaderPtr): OSErr;
VAR
    myVars:                 LocalVars;
    myDblHeader:            SndDoubleBufferHeader;
    myDblBuffer:            SndDoubleBufferPtr;
    myStatus:               SCStatus;
    myIndex:                Integer;
    myErr:                  OSErr;
BEGIN
    {Set up myVars with initial information.}
    myVars.bytesTotal := sndHeader^.length;
    myVars.bytesCopied := 0;                            {no samples copied yet}
    myVars.dataPtr := Ptr(@sndHeader^.sampleArea[0]);
                                                        {pointer to first sample}
    {Set up SndDoubleBufferHeader.}
    WITH myDblHeader DO
    BEGIN
        dbhNumChannels := 1;                            {one channel}
        dbhSampleSize := 8;                             {8-bit samples}
        dbhCompressionID := 0;                          {no compression}
        dbhPacketSize := 0;                             {no compression}
        dbhSampleRate := sndHeader^.sampleRate;
        dbhDoubleBack := @MyDoubleBackProc;
    END;

    FOR myIndex := 0 TO 1 DO                            {initialize both buffers}
    BEGIN
        {Get memory for double buffer.}
        myDblBuffer := SndDoubleBufferPtr(NewPtr(Sizeof(SndDoubleBuffer) +
                                                                    kDoubleBufferSize));
        IF myDblBuffer = NIL THEN
        BEGIN
            MyDBSndPlay := MemError;
            Exit(MyDBSndPlay);
        END;

        myDblBuffer^.dbNumFrames := 0;                  {no frames yet}
        myDblBuffer^.dbFlags := 0;                      {buffer is empty}
        myDblBuffer^.dbUserInfo[0] := LongInt(@myVars);

        {Fill buffer with samples.}
        MyDoubleBackProc(sndChan, myDblBuffer);

        {Store buffer pointer in header.}
        myDblHeader.dbhBufferPtr[myIndex] := myDblBuffer;
    END;
    {Start the sound playing.}
    myErr := SndPlayDoubleBuffer(sndChan, @myDblHeader);
    IF myErr <> noErr THEN
    BEGIN
        MyDBSndPlay := myErr;
        Exit(MyDBSndPlay);
    END;

    {Wait for the sound's end by checking the channel status.}
    REPEAT
        myErr := SndChannelStatus(chan, sizeof(myStatus), @status);
    UNTIL NOT myStatus.scChannelBusy;

    {Dispose double buffer memory.}
    FOR myIndex := 0 TO 1 DO
        DisposePtr(Ptr(myDblHeader.dbhBufferPtr[myIndex]));

    MyDBSndPlay := noErr;
END;

The function MyDBSndPlay takes two parameters, a pointer to a sound channel and a pointer to a sound header. For information about obtaining a pointer to a sound header, see "Obtaining a Pointer to a Sound Header" . The MyDBSndPlay function reads the sound header to determine the characteristics of the sound to be played (for example, how many samples are to be sent into the sound channel). Then MyDBSndPlay fills in the fields of the double buffer header, creates two buffers, and starts the sound playing. The doubleback procedure MyDoubleBackProc is defined in the next section.


© 1998 Apple Computer, Inc.

| Previous | Chapter contents | Chapter top | Section top | Next |